package com.it.jwt.service;

import com.it.common.domain.LoginUserDetails;
import com.it.common.domain.dos.*;
import com.it.common.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @author yu
 * @date 2024/12/29
 * 重写security UserDetailsService方法 从数据库中获取用户信息,将用户信息送到SpringSecurity上下文中
 */
@Service
@Slf4j
@Transactional
public class UserDetailServiceImpl implements UserDetailsService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Resource
    private PermissionMapper permissionMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDO userDo = userMapper.getUserByUserName(username);

        // 判断用户是否存在
        if (Objects.isNull(userDo)) {
            throw new UsernameNotFoundException("该用户不存在");
        }

        List<String> roles = new ArrayList<>();
        List<String> permissions = new ArrayList<>();

        List<UserRoleDO> userRoleDOS = userRoleMapper.getUserRoleByUserId(userDo.getId());
        if(!CollectionUtils.isEmpty(userRoleDOS)){
            List<Long> roleIds = userRoleDOS.stream().map(userRoleDO -> userRoleDO.getRoleId()).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(roleIds)){
                List<RoleDO> roleDOS = roleMapper.batchGetRolesByRoleIds(roleIds);
                if(!CollectionUtils.isEmpty(roleDOS)){
                    List<String> roleNames = roleDOS.stream().map(RoleDO -> RoleDO.getRoleName()).collect(Collectors.toList());
                    roles.addAll(roleNames);
                }

                List<RolePermissionDO> rolePermissionDOS = rolePermissionMapper.batchGetRolePermissionsByRoleIds(roleIds);
                if(!CollectionUtils.isEmpty(rolePermissionDOS)){
                    List<Long> permissionIds = rolePermissionDOS.stream()
                            .map(RolePermissionDO -> RolePermissionDO.getPermissionId()).collect(Collectors.toList());
                    if(!CollectionUtils.isEmpty(permissionIds)){
                        List<PermissionDO> permissionDOS = permissionMapper.batchGetPermissionsByPermissionIds(permissionIds);
                        if(!CollectionUtils.isEmpty(permissionDOS)){
                            List<String> permissionNames = permissionDOS.stream().
                                    map(PermissionDO -> PermissionDO.getPermissionName()).collect(Collectors.toList());
                            permissions.addAll(permissionNames);
                        }
                    }
                }
            }
        }

        return new LoginUserDetails(userDo, roles, permissions);
    }
}
